#ifndef _WORLD_HPP
#define _WORLD_HPP

#include <map>
#include <vector>

//Header du framework contenant les structures IntMatrix
#include "Variant.hpp"

#include "pathfinder.h"


#define DEBUG_INIT_WORLD    1
#define DEBUG_TURN          0

using namespace std;

class map_chunk;

typedef struct {
    int id;
    int type;
    int info;
    map_chunk* position;
} Object;

typedef Object Building;
//typedef Object Fruit;
#include "fruit.h"
#include "helper.h"

#define AREA_SPREAD 3
enum areas{
    area_none = 0,
    area_ourbase = 1,
    area_vitsource = 2,
    area_sugartree = 4
};

class map_chunk: public map_elm{

    public:
        vector<Object*> objects;
        Fruit*          fruit;
        Building*       building;

        unsigned int area_qualif;
        unsigned int valeurSucre;
        unsigned int danger_estimation;
        unsigned int value_estimation;

        map_chunk();
        ~map_chunk();

};

class World: public map_ctr<map_chunk> {
    private:

    unsigned int sugarCount;
    unsigned int vitaminCount;

    public:

    //Fruits, objets
    map<int, Fruit> ourFruits;
    map<int, Fruit> theirFruits;
    map<int, Object> items;

    //Zones
    vector<map_chunk*> ourbase;
    vector<map_chunk*> vitsource;
    vector<map_chunk*> sugartree;

    //Batiments des adversaires
    vector<Building> theirBuildings;

    //Batiments de notre base
    Building ourJuiceBarrel;
    Building ourSugarBowl;
    Building ourFructificationTank;

    //Batiments neutres
    Building theVitaminSource;
    Building theSugarTree;

    //Limites de fruits
    unsigned int maxKiwis;
    unsigned int maxCherries;
    unsigned int maxNuts;

    //Nombre d'équipes adverses
    unsigned int nOpponents;

    World();
    ~World();

    //Permettent de connaître la quantité de sucre et de vitamines en stock
    unsigned int getSugarCount();
    unsigned int getVitaminCount();

    //Fonction appelées lors de la mise à jour des quantités de sucre et de vitamines
    //(loot de vitamine, dépôt de sucre, achat/vente, création de fruit)
    bool updateSugarCount(signed int val);
    bool updateVitaminCount(signed int val);

    //Fonction appelée dans la méthode initGame ; remplit les infos du monde
    void initWorld(IntMatrix2 architecture,
		IntMatrix2 fruits, IntMatrix2 buildings,
		int limitCherry, int limitKiwi, int limitNut,
		int vitaminGoal, int maxNbTurns);
    //Fonction appelée au début de playTurn : met à jour les infos du monde
    void updateAtBeginningOfTurn(IntMatrix2& newObjects,
		IntMatrix1& deletedObjects, IntMatrix2& movedFruits,
		IntMatrix2& modifiedFruits, IntMatrix2& modifiedSugarDrops);
    //Fonction appelée au cours d'un tour (ex: kill ou ouverture de coffre)
    void updateDuringTurn(IntMatrix2 &newObjects, IntMatrix2 &modifiedSugarDrops);

    //Calcul des valeurs de la map
    void computeDanger();
    void computeValue();

    //Création des zones (à ne lancer qu'à l'init)
    void makeAreas();

    //Virtual héritées à modifier
   // void getNeighborhood( pfNode<map_chunk>* node, list< pfNode<map_chunk>* >* neighborhood);
    bool isWalkable(map_chunk* chk);
    //Affiche les infos sur la carte
    void printInfos();
    void getNeighborhood( pfNode<map_chunk>* node, list< pfNode<map_chunk>* >* neighborhood);

    int fructify(int fruitType, int x, int y);

};

vector<Object*>::iterator getIteratorToObject(int objectId, vector<Object*>& vec);

#endif
